/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dljs.classes;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 *
 * @author vova
 */
public class SolitareEngine {
    public SolitareEngine() {
        m_cardSet = new CSolitareCardSet();
        
        Deck tmpDeck2 = new Deck();
        tmpDeck2.of52Cards();
        tmpDeck2.setSolitarePriority();
        tmpDeck2.shuffle();    
    
        m_cardSet.m_field1[0]=null;      
        m_cardSet.m_field1[1]=null;
        m_cardSet.m_field1[2]=null;
        m_cardSet.m_field1[3]=null;
        
        int i=0;
        while(!tmpDeck2.isEmpty()){
            m_cardSet.m_field3[i].add(tmpDeck2.getTop());
            i++;
            if(i>=8) i=0;
        }  
    }
    
    public void Field1Clicked(int nPos) {
        //System.out.println("you click on panel 1 position = "+nPos);
        //if (m_cardSet.m_field1[nPos] == null) return;
        int nSelField = getSelectedField();
        int nSelCol = getSelectedColumn(nSelField);
        
        switch (nSelField) {
        case -1:
            // нет выбранных карт
            if (m_cardSet.m_field1[nPos] != null)
                m_cardSet.m_field1[nPos].setSelected(true);
            break;
            
        case 1:
            // выбранная карта в этом же поле       
            m_cardSet.m_field1[nSelCol].setSelected(false);
            if ((nSelCol != nPos) && (m_cardSet.m_field1[nPos] != null))
                m_cardSet.m_field1[nPos].setSelected(true);
            break;
            
        case 2:
            // выбранная карта в поле 2
            // такого быть не должно
            break;
            
        case 3:
            // выбранная карта в поле 3
            if (m_cardSet.m_field1[nPos] == null) {
                MoveLastCard(nSelField, nSelCol, 1, nPos);
            }
            break;
            
        default:
            Logger.getLogger(SolitareEngine.class.getName()).log(Level.SEVERE, "Field1Clicked - неправльное поле");
            break;
        }
    }
    
    public void Field2Clicked(int nPos) {
        //System.out.println("you click on panel 2 position = "+nPos);
        int nSelField = getSelectedField();
        int nSelCol = getSelectedColumn(nSelField);
        
        // выделять карты в этом поле не допускаетсчя правилами игры
        if (nSelField == -1) return;
        
        MoveLastCard(nSelField, nSelCol, 2, nPos);
    }
    
    public void Field3Clicked(int nPos) {
        //System.out.println("you click on panel 3 position = "+nPos);
        int nSelField = getSelectedField();
        int nSelCol = getSelectedColumn(nSelField);
        
        if (nSelField == -1) {
            // нет выбранных карт
            // выделяем последнюю в выбранном ряду
            if (m_cardSet.m_field3[nPos].isEmpty()) return;
            m_cardSet.m_field3[nPos].get(m_cardSet.m_field3[nPos].size()-1).setSelected(true);
        } else if (nSelField == 3) {
            // выбранная карта в этом же поле
            if (nPos == nSelCol)
                // если в тойже колонке, то снимаем выделение
                for (CCard aCard : m_cardSet.m_field3[nPos]) aCard.setSelected(false);
            else {
                // выбранная карта в одной колонке, пользователь выбрал другую
                MoveLastCard(nSelField, nSelCol, 3, nPos);
            }
        } else if (nSelField == 1) {
            // выбранная карта в другом поле
            MoveLastCard(nSelField, nSelCol, 3, nPos);
        }
    }
    
    public CSolitareCardSet getCardSet() {
        return m_cardSet.clone();
    }
    
    private boolean isSelectedInFields(ArrayList<CCard>[] ars) {
        for (int i=0; i<ars.length; i++)
            for (CCard aCard : ars[i]) {
                if (aCard == null) continue;
                if (aCard.getSelected()) return true;
            }
        
        return false;
    }
    
    private boolean MoveValidator(int nSourceField, int nSourceColumn, int nDestField, int nDestColumn) {
        // в поле 1 можно ложить любую карту
        if (nDestField == 1) return true;
        
        // в поле 2 можно ложить большую карту на меньшую одной масти
        // на пустое поле можно положить только туза
        if (nDestField == 2) {
            // есть ли карта - источник?
            CCard sourceCard = null;
            if ((nSourceField == 1) && (m_cardSet.m_field1[nSourceColumn]!=null))
                sourceCard = m_cardSet.m_field1[nSourceColumn];
            else if ((nSourceField == 2) && (!m_cardSet.m_field2[nSourceColumn].isEmpty()))
                sourceCard = m_cardSet.m_field2[nSourceColumn].get(m_cardSet.m_field2[nSourceColumn].size()-1);
            else if ((nSourceField == 3) && (!m_cardSet.m_field3[nSourceColumn].isEmpty()))
                sourceCard = m_cardSet.m_field3[nSourceColumn].get(m_cardSet.m_field3[nSourceColumn].size()-1);
            
            if (sourceCard == null) return false;
            
            CCard destCard;
            int tmpRankSource;
            int tmpRankDest;
            if (m_cardSet.m_field2[nDestColumn].isEmpty()) {
                // пустое место, ложим только туза
                if (sourceCard.getRank() == 14) return true;
            } else {
                // в поле карты уже есть, ложим достоинство+1, одной масти
                destCard = m_cardSet.m_field2[nDestColumn].get(m_cardSet.m_field2[nDestColumn].size()-1);
                if (sourceCard.getSuite() != destCard.getSuite()) return false;
                tmpRankSource = sourceCard.getRank();
                tmpRankDest = destCard.getRank();
                if (tmpRankSource == 14) tmpRankSource = 1;
                if (tmpRankDest == 14) tmpRankDest = 1;
                if (tmpRankDest == --tmpRankSource) return true;
            }
        }
        
        // в поле 3 ложим меньшую карту на большую разного цвета
        // ??? на пустое поле можно положить любую карту ???
        if (nDestField == 3) {
            // есть ли карта - источник?
            CCard sourceCard = null;
            if ((nSourceField == 1) && (m_cardSet.m_field1[nSourceColumn]!=null))
                sourceCard = m_cardSet.m_field1[nSourceColumn];
            else if ((nSourceField == 2) && (!m_cardSet.m_field2[nSourceColumn].isEmpty()))
                sourceCard = m_cardSet.m_field2[nSourceColumn].get(m_cardSet.m_field2[nSourceColumn].size()-1);
            else if ((nSourceField == 3) && (!m_cardSet.m_field3[nSourceColumn].isEmpty()))
                sourceCard = m_cardSet.m_field3[nSourceColumn].get(m_cardSet.m_field3[nSourceColumn].size()-1);
            
            if (sourceCard == null) return false;
            CCard destCard;
            int tmpRankSource;
            int tmpRankDest;
            int tmpSourceSuiteColor;
            int tmpDestSuiteColor;
            if (m_cardSet.m_field3[nDestColumn].isEmpty()) {
                // пустое место, ложим любую карту
                return true;
            } else {
                // ложим меньшую карту на большую разного цвета
                destCard = m_cardSet.m_field3[nDestColumn].get(m_cardSet.m_field3[nDestColumn].size()-1);
                if ((sourceCard.getSuite()==ECardSuite.CLUBS) || (sourceCard.getSuite()==ECardSuite.SPADES))
                    tmpSourceSuiteColor = 0;
                else tmpSourceSuiteColor = 1;
                if ((destCard.getSuite()==ECardSuite.CLUBS) || (destCard.getSuite()==ECardSuite.SPADES))
                    tmpDestSuiteColor = 0;
                else tmpDestSuiteColor = 1;
                tmpRankSource = sourceCard.getRank();
                tmpRankDest = destCard.getRank();
                if (tmpRankSource == 14) tmpRankSource = 1;
                if (tmpRankDest == 14) tmpRankDest = 1;
                if ((tmpSourceSuiteColor!=tmpDestSuiteColor) && (tmpRankSource==--tmpRankDest))
                    return true;
            }
        }
        
        return false;
    }
    
    private void MoveLastCard(int nSourceField, int nSourceColumn, int nDestField, int nDestColumn) {
        if (!MoveValidator(nSourceField, nSourceColumn, nDestField, nDestColumn)) return;
        
        CCard movedCard = null;
        int nLastCard;
        
        if (nSourceField == 1) {
            movedCard = m_cardSet.m_field1[nSourceColumn];
            m_cardSet.m_field1[nSourceColumn] = null;
        } else if ((nSourceField == 2) && (!m_cardSet.m_field2[nSourceColumn].isEmpty())) {
            nLastCard = m_cardSet.m_field2[nSourceColumn].size()-1;
            movedCard = m_cardSet.m_field2[nSourceColumn].remove(nLastCard);
        } else if ((nSourceField == 3) && (!m_cardSet.m_field3[nSourceColumn].isEmpty())) {
            nLastCard = m_cardSet.m_field3[nSourceColumn].size()-1;
            movedCard = m_cardSet.m_field3[nSourceColumn].remove(nLastCard);
        }
        
        if (movedCard == null) return;
        movedCard.setSelected(false);
        
        if (nDestField == 1)
            m_cardSet.m_field1[nDestColumn] = movedCard;
        else if (nDestField == 2)
            m_cardSet.m_field2[nDestColumn].add(movedCard);
        else if (nDestField == 3)
            m_cardSet.m_field3[nDestColumn].add(movedCard);
    }
    
    // номер поля, в котором лежит выбранная карта
    // 0 - нет выбранных карт
    private int getSelectedField() {            
        if (m_cardSet.m_field1[0] != null) {
            if (m_cardSet.m_field1[0].getSelected()) return 1;
        }
        if (m_cardSet.m_field1[1] != null) {
            if (m_cardSet.m_field1[1].getSelected()) return 1;
        }
        if (m_cardSet.m_field1[2] != null) {
            if (m_cardSet.m_field1[2].getSelected()) return 1;
        }
        if (m_cardSet.m_field1[3] != null) {
            if (m_cardSet.m_field1[3].getSelected()) return 1;
        }
        if (isSelectedInFields(m_cardSet.m_field2)) return 2;
        if (isSelectedInFields(m_cardSet.m_field3)) return 3;
        
        return -1;
    }
    
    // номер колонки с выбранной картой
    // -1 - не нашли выбранную карту
    private int getSelectedColumn(int nField) {
        if (nField == 1) {
            if (m_cardSet.m_field1[0] != null)
                if (m_cardSet.m_field1[0].getSelected()) return 0;
            if (m_cardSet.m_field1[1] != null)
                if (m_cardSet.m_field1[1].getSelected()) return 1;
            if (m_cardSet.m_field1[2] != null)
                if (m_cardSet.m_field1[2].getSelected()) return 2;
            if (m_cardSet.m_field1[3] != null)
                if (m_cardSet.m_field1[3].getSelected()) return 3;
        } else if (nField == 2) {
            for (int i=0; i<m_cardSet.m_field2.length; i++)
                for (CCard aCard : m_cardSet.m_field2[i])
                    if (aCard.getSelected()) return i;
        } else if (nField == 3) {
            for (int i=0; i<m_cardSet.m_field3.length; i++)
                for (CCard aCard : m_cardSet.m_field3[i])
                    if (aCard.getSelected()) return i;
        }
        
        return -1;
    }
    
    private CSolitareCardSet m_cardSet;
}
